
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from "vscode";
import * as path from "path";
import * as fs from "fs";
import * as os from "os";
import { ViewManager, SidebarViewProvider } from "./common/viewManager";
import localize from "./localize";
import { CManager } from "./templates/cManager";
import { CreatePage } from "./templates/createPage";
import { OperationPage } from "./templates/operationPage";

import * as utils from "./utils";
// import { utils } from 'mocha';
import * as fse from "fs-extra";

export let gContext: any;
// export let gLicenseBundle: any;

export class ProjectManager {
  context: vscode.ExtensionContext;
  CreatePage: any;
  cObject: any;
  operationPage: any;

  constructor(context: vscode.ExtensionContext) {
    this.context = context;
    this.cObject = new CManager(this.context);
    this.CreatePage = new CreatePage(this.context);
    this.operationPage = new OperationPage(this.context);
  }
  
  public createPage() {
    this.context.subscriptions.push(this.CreatePage.registerCreatePage());
  }

  public operationPageCreate() {
    this.operationPage.registerOperationPages(this.context);
    // this.context.subscriptions.push(this.operationPage.registerOperationPage());
    // this.context.subscriptions.push(this.operationPage.registerOperationPage());
  }
}

/**
 * 创建项目文件夹
 * @param message 用户配置数据
 * @param projectPath 本地项目目录
 * @returns
 */
async function createFiles(message: any, projectPath: string) {
  try {
    //项目类型: c  c++ ...
    const type = message.data.projectType;
    // 子类型
    const subType = message.data.projectSubType;
    // 项目构建类型 makefile cmake ...
    const buildTools = message.data.buildTools;
    console.log(path.join(gContext.extensionPath, "templates", type, subType, buildTools))
    //拷贝项目所有文件到项目目录下
    fse.copySync(
      path.join(gContext.extensionPath, "templates", type, subType, buildTools),
      projectPath
    );

    if (
      (type === "c" &&
        buildTools == "makefile") ||
      (type === "c++" &&
        buildTools == "makefile")
    ) {
    
      let filename = undefined;
      if(type == "c"){
        filename = "src/main.c"
      }
      else if(type == "c++"){
        filename = "src/main.cpp"
      }
    
      if(filename != undefined){
        // 修改作者信息等
        await modifyAuthorInfo(projectPath, message, filename);
      }
    }

    if (
      (type === "c" &&
        // subType != "blank" &&
        message.data.CompileC != "/usr/bin/gcc") ||
      (type === "c++" &&
        // subType != "blank" &&
        message.data.CompileC != "/usr/bin/g++")
    ) {
      // 修改编译器路径
      await modifyCompilePath(projectPath, message);
    }
  } catch (err) {
    console.error(err);
  }
}

/**
 * 修改作者信息
 * @param projectPath 项目目录
 * @param message 数据
 */
 export async function modifyAuthorInfo(projectPath: string, message: any, fileName: string) {
  console.log("--- modifyAuthorInfo");
  //设置读取配置路径，默认是 build = qmake
  var configPath = path.join(projectPath, fileName);

  //读取配置
  var contents = undefined;
  try {
    contents = fse.readFileSync(configPath, "utf-8");
  } catch (e) {
    console.log(e);
  }

  // licenses
  
  const licensesFilePath = path.join(gContext.extensionPath, "src/common/licenses.json");
  const resolvedLicensesBundle = JSON.parse(
    fse.readFileSync(licensesFilePath, "utf-8")
  );
  // if(gLicenseBundle == undefined){
  //   gLicenseBundle = resolveLicensePack();
  // }
  console.log("resolvedLicensesBundle:");
  console.log(resolvedLicensesBundle)
  console.log(resolvedLicensesBundle[message.data.licenses])
  if (contents != undefined) {
    // 修改 main.c main.cpp ...
    // console.log('newContents \n' + contents);
    contents = contents.replace(/\$\$LICENSE\$\$/g, resolvedLicensesBundle[message.data.licenses]);
    contents = contents.replace(/\$\$YEAR\$\$/g, utils.getYear() + "");
    contents = contents.replace(/\$\$AUTHOR\$\$/g, message.data.author);
    contents = contents.replace(/\$\$EMAIL\$\$/g, message.data.email);
    contents = contents.replace(/\$\$VERSION\$\$/g, message.data.version);

    // 重新写回配置
    fse.writeFileSync(configPath, contents);
  }
}
/**
 * 修改CMakeLists.txt
 * @param projectPath 项目目录
 * @param message 数据
 */
 export async function modifyCMakeListsInfo(projectPath: string, message: any, fileName: string) {
  console.log("--- modifyAuthorInfo");
  //设置读取配置路径，默认是 build = qmake
  var configPath = path.join(projectPath, fileName);

  //读取配置
  var contents = undefined;
  try {
    contents = fse.readFileSync(configPath, "utf-8");
  } catch (e) {
    console.log(e);
  }

  // licenses
  
  const licensesFilePath = path.join(gContext.extensionPath, "src/common/licenses.json");
  const resolvedLicensesBundle = JSON.parse(
    fse.readFileSync(licensesFilePath, "utf-8")
  );
  if (contents != undefined) {
    // 修改 CMakeLists.txt 
    console.log("cmakelists.txt path :",configPath);
    console.log("message.data.outputFileName :",message.data.outputFileName);
    contents = contents.replace(/\$\$outputFileName\$\$/g, message.data.outputFileName);

    // 重新写回配置
    fse.writeFileSync(configPath, contents);
  }
}
/**
 * qmake/cmake 指定编译器路径
 * @param projectPath 项目目录
 * @param message 数据
 */
export async function modifyCompilePath(projectPath: string, message: any) {
  console.log("--- modifyCompilePath");
  //设置读取配置路径，默认是 build = qmake
  var configPath = path.join(projectPath, "Makefile");

  //读取配置
  var value = undefined;
  try {
    value = fse.readFileSync(configPath, "utf-8");
  } catch (e) {
    console.log(e);
  }

  if (value != undefined) {
    //添加新配置
    var newValue = "";
    var valueArray = value.split("\n");
    for (var i = 0; i < valueArray.length; ++i) {
      if (
        message.data.projectType === "c" &&
        valueArray[i].indexOf("CC = gcc") >= 0
      ) {
        newValue += `CC = ${message.data.CompileC}` + "\n";
      } else if (
        message.data.projectType === "c++" &&
        valueArray[i].indexOf("CXX = g++") >= 0
      ) {
        newValue += `CXX = ${message.data.CompileCXX}` + "\n";
      } else {
        newValue += valueArray[i] + "\n";
      }
    }

    // 重新写回配置
    fse.writeFileSync(configPath, newValue);
  }
}

/**
 * 创建项目
 * @param message 用户配置数据
 */
export async function createProject(
  message: any,
  viewPanel: vscode.WebviewPanel
) {
  //test
  console.log("CompileMoudle createProject");
  console.log("type : " + message.data.projectType);
  console.log("buildTools : " + message.data.buildTools);
  console.log("subtype : " + message.data.projectSubType);

  //项目类型: c  c++ ...
  const type = message.data.projectType;
  // 子类型
  const subType = message.data.projectSubType;
      // 项目构建类型 makefile cmake ...
  const buildTools = message.data.buildTools;

  if (message.data.projectType && message.data.projectSubType) {
    //创建项目主目录, java maven 不在此处创建目录
    const projectDir = `${message.data.projectPath}/${message.data.projectName}`;
    if (message.data.projectSubType != "maven") {
      // 创建目录
      await utils.createDir(projectDir);
    }
    if (
      (message.data.projectType === "c" &&
        message.data.projectSubType === "default") ||
      (message.data.projectType === "key-clus-project" &&
        message.data.projectSubType === "default")
    ) {
      // 创建目录
      await utils.createDir(`${projectDir}/include`);
      // 创建目录
      await utils.createDir(`${projectDir}/lib`);
    }

    if (message.data.projectType === "key-qt-project" ||
        (message.data.projectType === "c" && buildTools === "cmake")) {
      await utils.createDir(`${projectDir}/build`);
    }

    // 拷贝其它模板文件
    await createFiles(message, projectDir);

    // 写入配置参数

    //将创建的项目显示到工作区
    const uri = vscode.Uri.file(projectDir);
    //页面消失操作
    viewPanel.dispose();
    // 执行打开新工程命令
    vscode.commands.executeCommand("vscode.openFolder", uri);

    utils.showInfo(localize("language.CreateProjectSuccess"));
  } else {
    utils.showError(localize("language.CreateProjectError"));
  }
}

export async function resolveLicensePack() {

  try {
    var rootPath = vscode.extensions?.getExtension("kylin.vscode-create-project")?.extensionPath;
    if(rootPath === undefined)
    {
        rootPath = vscode.extensions.getExtension.name;
    }
    const licensesFilePath = path.resolve(rootPath, "src/common/licenses.json");
    
    const resolvedLicensesBundle = JSON.parse(
      fse.readFileSync(licensesFilePath, "utf-8")
    );

    return resolvedLicensesBundle;
    // return { ...resolvedLicensesBundle};
  } catch (err) {
    throw err;
  }
}


// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export async function activate(context: vscode.ExtensionContext) {
  gContext = context;
  
  //const serviceManager = new ServiceManager(context)
  ViewManager.initExtesnsionPath(context.extensionPath);
  // gLicenseBundle = resolveLicensePack();

  var vsprojectidepath;
  let projectManager = new ProjectManager(context);

  projectManager.createPage();
  projectManager.operationPageCreate();

  console.log("activate:");
  console.log(vscode.workspace.rootPath)
  if (vscode.workspace.rootPath) {
    vsprojectidepath = vscode.workspace.rootPath + "/" + "vsproject.ide.json";
    if (
      fs.existsSync(vsprojectidepath) &&
      fs.statSync(vsprojectidepath).isFile()
    ) {
      let vsprojectidejson = JSON.parse(
        fs.readFileSync(vsprojectidepath, "utf8")
      );
      const languagedata = vsprojectidejson["language"];
      const templatedata = vsprojectidejson["template"];
    }
  }

  let loadDir: string = os.homedir();
  let options = {
    canSelectFiles: false, //Whether to select files
    canSelectFolders: true, //Whether to choose a directory
    canSelectMany: false, //Can multiple choices
    defaultUri: vscode.Uri.file(loadDir), //The folder opened by default
    openLabel: localize("language.OpenDirectory"),
  };

}
// this method is called when your extension is deactivated
export function deactivate() {}
